import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Map;

import javax.imageio.ImageIO;

import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.events.ServerMessageEvent;
import com.speljohan.rsbot.event.listeners.PaintListener;
import com.speljohan.rsbot.event.listeners.ServerMessageListener;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSObject;
import com.speljohan.rsbot.script.wrappers.RSTile;
import com.speljohan.rsbot.util.ScreenshotUtil;

class AntiBanThread extends Thread implements
		com.speljohan.rsbot.plugin.NonPluginClass {
	@Override
	public void run() {
		setName("AntiBan Thread");
		SmartBury theScript;
		theScript = new SmartBury();
		final int Camera = theScript.random(1, 10);
		if (Camera < 5) { // Credits to WarXperiment
			final char[] LR = new char[] { KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT };
			final char[] UD = new char[] { KeyEvent.VK_DOWN, KeyEvent.VK_UP };
			final char[] LRUD = new char[] { KeyEvent.VK_LEFT,
					KeyEvent.VK_RIGHT, KeyEvent.VK_UP, KeyEvent.VK_UP };
			final int random2 = theScript.random(0, 2);
			final int random1 = theScript.random(0, 2);
			final int random4 = theScript.random(0, 4);

			if (theScript.random(0, 3) == 0) {
				Bot.getInputManager().pressKey(LR[random1]);
				try {
					Thread.sleep(theScript.random(100, 400));
				} catch (final Exception e) {
				}
				Bot.getInputManager().pressKey(UD[random2]);
				try {
					Thread.sleep(theScript.random(300, 600));
				} catch (final Exception e) {
				}
				Bot.getInputManager().releaseKey(UD[random2]);
				try {
					Thread.sleep(theScript.random(100, 400));
				} catch (final Exception e) {
				}
				Bot.getInputManager().releaseKey(LR[random1]);
			} else {
				Bot.getInputManager().pressKey(LRUD[random4]);
				if (random4 > 1) {
					try {
						Thread.sleep(theScript.random(300, 600));
					} catch (final Exception e) {
					}
				} else {
					try {
						Thread.sleep(theScript.random(500, 900));
					} catch (final Exception e) {
					}
				}
				Bot.getInputManager().releaseKey(LRUD[random4]);
			}
		}
	}
}

public class SmartBury extends Script implements PaintListener,
		ServerMessageListener {

	public enum Process {
		bury, bank, stop;
	}

	public String State = "Not Yet Started";
	BufferedImage img = null;

	AntiBanThread AntiBan;
	public long StartTime;
	public int BoneID;
	public int amount;
	public long expGained;
	public int levelsGained;
	public int startExp;
	public int startLevel;
	public int BonesUntilLevel;
	public int expPerBone;
	public long buried = 0;
	public long xpPerHour;
	public int customBankID;
	public int[] bankBooths = { 36831, 11758, 36831, 26972, 11402, 35647, 2213,
			24914, 36786, 11402, 35678, 14367, customBankID };
	public boolean randomBury;
	public boolean update;
	public boolean UpToDate;

	public boolean Tele;

	public void checkVersion() {
		try {
			final URL url = new URL("http://gamedepot.bplaced.net/version.txt");
			final BufferedReader reader = new BufferedReader(
					new InputStreamReader(url.openStream()));
			String line;
			final String version = Double.toString(getVersion());
			while ((line = reader.readLine()) != null) {
				if (line.contains(version)) {
					UpToDate = true;
				} else {
					UpToDate = false;
				}
			}
		} catch (final IOException e) {
			e.printStackTrace();
		}
	}

	public void deposit() {
		if (getInventoryCountExcept(BoneID) > 0) {
			bank.depositAllExcept(BoneID);
		}
		if (getEquipmentCount() > 0) {
			bank.depositAllEquipped();
		}
		wait(random(200, 400));
	}

	@Override
	public String getAuthor() {
		return "Master T and Tahayassen";
	}

	@Override
	public String getName() {
		return "Smart Bury";
	}

	public Process getProcess() {
		if (buried >= amount - 1) {
			return Process.stop;
		}
		if (getInventoryCount(BoneID) > 0) {
			return Process.bury;
		} else {
			return Process.bank;
		}
	}

	@Override
	public String getScriptCategory() {
		return "Prayer";
	}

	@Override
	public String getScriptDescription() {
		return "<html><head><style type=text/css>.style1 {color: #FFFFFF;}.style2 {color: #FFFFFF;font-weight: bold;}</style></head><body bgcolor=\"black\" text=\"white\"><center><table border=0><tr><td width=\"350\"></p><tr><td class=style2>Bone Bury Method: </td><td width=\"156\" align=\"left\" class=style1><select name=order style=width: 205px><option>Bury Bones Randomly</option><option>Bury Bones In Order</option></tr></td><tr><td class=style2>Bone to bury: </td><td width=\"156\" align=\"left\" class=style1><select name=bone><option>Normal Bones</option><option>Wolf Bones</option><option>Burnt Bones</option><option>Monkey Bones</option><option>Bat Bones</option><option>Big Bones</option><option>Jogre Bones</option><option>Zogre Bones</option><option>Shaikahan Bones</option><option>Babydragon Bones</option><option>Wyvern Bones</option><option>Dragon Bones</option><option>Fayrg Bones</option><option>Raurg Bones</option><option>Dagannoth Bones</option><option>Ourg Bones</option></select></td></tr><tr><td class=style2>Amount to Bury: </td><td align=\"right\" class=style1><input type=\"text\" name=\"amount\" id=\"amount\" VALUE=1000 style=width: 95px></td></tr><tr><td class=style2>Custom Bank ID: </td><td align=\"right\" class=style1><input type=\"text\" name=\"bankID\" id=\"bankID\" style=width: 95px></td></tr><tr><td class=style2>Use Custom Bank:</td><td class=style1><INPUT TYPE=checkbox NAME=customBank VALUE=false></td></tr><tr><td class=style2>Teleport to Lumbridge if Bank is not found:</td><td class=style1><INPUT TYPE=checkbox NAME=tele VALUE=true CHECKED=true></td></tr><tr><td class=style2>Check for Updates:</td><td class=style1><INPUT TYPE=checkbox NAME=update VALUE=true CHECKED=true></td></tr></select></td></tr></table></center></body></html>";
	}

	@Override
	public double getVersion() {
		return 2.9;
	}

	@Override
	public int loop() {
		switch (getProcess()) {
		case bury:
			State = "Burying";
			AntiBan.run();
			if (randomBury) {
				randomBury(BoneID);
				return random(200, 400);
			} else {
				orderBury(BoneID);
				return random(400, 500);
			}

		case bank:
			State = "Banking";
			final RSObject Bank = getNearestObjectByID(bankBooths);
			if (Bank != null) {
				final RSTile BankLocation = Bank.getLocation();
				if (!tileOnScreen(BankLocation)) {
					walkTileMM(randomizeTile(BankLocation, 2, 2));
				}
				if (!bank.isOpen()) {
					atObject(Bank, "Use-quickly");
					wait(random(200, 400));
				} else {
					deposit();
					withdraw();
				}
			}
			if (Bank == null & Tele) {
				State = "Closing script.";
				log("Sorry, we still didn't install Lumbridge teleport!");
				ScreenshotUtil.takeScreenshot(isLoggedIn());
				stopAllScripts();
			}
			if (Bank == null & !Tele) {
				State = "Closing script.";
				log("Bank could not be found. Teleport is disabled. Closing script...");
				ScreenshotUtil.takeScreenshot(isLoggedIn());
				stopAllScripts();
			}
			return random(200, 400);

		case stop:
			State = "Closing script.";
			log("Finished amount of bones needed to be buried.");
			ScreenshotUtil.takeScreenshot(isLoggedIn());
			stopAllScripts();
		}
		return -1;
	}

	@Override
	public void onFinish() {
		log("Thanks for using the script!");
		log("XP per hour: " + xpPerHour);
		log("Levels Gained: " + levelsGained);
		log("Buried: " + buried + " Bones");
		log("Experience Gained: " + expGained);
		AntiBan.interrupt();
	}

	public void onRepaint(final Graphics Taha) {
		if (isLoggedIn()) {
			if (StartTime == 0) {
				StartTime = System.currentTimeMillis();
			}

			final long RunTime = System.currentTimeMillis() - StartTime;
			final long TotalSecs = RunTime / 1000;
			final long TotalMins = TotalSecs / 60;
			final long TotalHours = TotalMins / 60;
			final int seconds = (int) TotalSecs % 60;
			final int minutes = (int) TotalMins % 60;
			final int hours = (int) TotalHours % 60;

			final StringBuilder b = new StringBuilder();
			if (hours < 10) {
				b.append('0');
			}
			b.append(hours);
			b.append(':');
			if (minutes < 10) {
				b.append('0');
			}
			b.append(minutes);
			b.append(':');
			if (seconds < 10) {
				b.append('0');
			}
			b.append(seconds);

			if (startExp == 0) {
				startExp = skills.getCurrentSkillExp(Constants.STAT_PRAYER);
			}

			if (startLevel == 0) {
				startLevel = skills.getCurrentSkillLevel(Constants.STAT_PRAYER);
			}

			expGained = skills.getCurrentSkillExp(Constants.STAT_PRAYER)
					- startExp;
			levelsGained = skills.getCurrentSkillLevel(Constants.STAT_PRAYER)
					- startLevel;

			if (expPerBone == 0) {
				expPerBone = skills.getCurrentSkillExp(Constants.STAT_PRAYER)
						- startExp;
			}

			if (expPerBone != 0) {
				BonesUntilLevel = skills
						.getXPToNextLevel(Constants.STAT_PRAYER)
						/ expPerBone;
			}

			if (expGained != 0) {
				xpPerHour = expGained * 3600 / (RunTime / 1000);
			}

			Taha.setColor(Color.WHITE);
			Taha.drawImage(img, 4, 200, null);
			Taha.setColor(Color.RED);
			Taha.setFont(new Font("Trebuchet MS", Font.PLAIN, 12));
			Taha.drawString(getName() + " v" + getVersion(), 9, 219);
			Taha.drawString("Experience Gained: " + expGained, 9, 235);
			Taha.drawString("Levels Gained: " + levelsGained, 9, 251);
			Taha.drawString("XP per hour: " + xpPerHour, 9, 267);
			Taha.drawString("Bones Until Next Level: " + BonesUntilLevel, 9,
					283);
			Taha.drawString("Buried: " + buried + " Bones", 9, 299);
			Taha.drawString("Time Running: " + hours + ":" + minutes + ":"
					+ seconds, 9, 315);
			Taha.drawString("Status: " + State, 9, 331);
			Taha.setColor(Color.WHITE);
			Taha.drawString("Level Progress", 10, 25);
			Taha.setColor(Color.RED);
			Taha.fill3DRect(10, 31, 500, 13, true);
			Taha.setColor(Color.GREEN);
			Taha
					.fill3DRect(10, 31, skills
							.getPercentToNextLevel(Constants.STAT_PRAYER) * 5,
							13, true);
		}
	}

	@Override
	public boolean onStart(final Map<String, String> args) {
		if (args.get("bone").equals("Normal Bones")) {
			BoneID = 526;
		}
		if (args.get("bone").equals("Wolf Bones")) {
			BoneID = 2859;
		}
		if (args.get("bone").equals("Burnt Bones")) {
			BoneID = 528;
		}
		if (args.get("bone").equals("Monkey Bones")) {
			BoneID = 3183;
		}
		if (args.get("bone").equals("Bat Bones")) {
			BoneID = 530;
		}
		if (args.get("bone").equals("Big Bones")) {
			BoneID = 532;
		}
		if (args.get("bone").equals("Jogre Bones")) {
			BoneID = 3125;
		}
		if (args.get("bone").equals("Zogre Bones")) {
			BoneID = 4812;
		}
		if (args.get("bone").equals("Shaikahan Bones")) {
			BoneID = 3123;
		}
		if (args.get("bone").equals("Babydragon Bones")) {
			BoneID = 534;
		}
		if (args.get("bone").equals("Wvyern Bones")) {
			BoneID = 6812;
		}
		if (args.get("bone").equals("Dragon Bones")) {
			BoneID = 536;
		}
		if (args.get("bone").equals("Fayrg Bones")) {
			BoneID = 4830;
		}
		if (args.get("bone").equals("Raurg Bones")) {
			BoneID = 4832;
		}
		if (args.get("bone").equals("Dagannoth Bones")) {
			BoneID = 6729;
		}
		if (args.get("bone").equals("Ourg Bones")) {
			BoneID = 4834;
		}
		if (args.get("order").equals("Bury Bones Randomly")) {
			randomBury = true;
		}
		if (args.get("customBank") != null) {
			customBankID = Integer.valueOf(args.get("bankID"));
		}
		if (args.get("update") != null) {
			update = true;
		}
		if (args.get("Tele") != null) {
			Tele = true;
		}
		amount = Integer.parseInt(args.get("amount"));
		try {
			final URL url = new URL(
					"http://img504.imageshack.us/img504/5711/backround.png");
			img = ImageIO.read(url);
		} catch (final IOException e) {
			log("Failed to get background image for the paint.");
		}
		checkVersion();
		if (update) {
			if (UpToDate) {
				log("Script is up to date.");
			} else {
				State = "WARNING!";
				log("WARNING: SCRIPT IS NOT UP TO DATE.");
			}
		} else {
			log("Update check was not peformed.");
		}
		try {
			new URL("http://www.ipcounter.us/count.php?counter=766")
					.openStream();
		} catch (final IOException e) {
			e.printStackTrace();
		}
		AntiBan = new AntiBanThread();
		return true;
	}

	public boolean orderBury(final int itemID) {
		if (getCurrentTab() != Constants.TAB_INVENTORY
				&& !RSInterface.getInterface(Constants.INTERFACE_BANK)
						.isValid()
				&& !RSInterface.getInterface(Constants.INTERFACE_STORE)
						.isValid()) {
			openTab(Constants.TAB_INVENTORY);
		}
		final int[] items = getInventoryArray();
		final java.util.List<Integer> possible = new ArrayList<Integer>();
		for (int i = 0; i < items.length; i++) {
			if (items[i] == itemID) {
				possible.add(i);
			}
		}
		if (possible.size() == 0) {
			return false;
		}
		final int idx = possible.get(0);
		final Point t = getInventoryItemPoint(idx);
		clickMouse(t, 5, 5, true);
		return true;
	}

	public boolean randomBury(final int itemID) {
		if (getCurrentTab() != Constants.TAB_INVENTORY
				&& !RSInterface.getInterface(Constants.INTERFACE_BANK)
						.isValid()
				&& !RSInterface.getInterface(Constants.INTERFACE_STORE)
						.isValid()) {
			openTab(Constants.TAB_INVENTORY);
		}
		final int[] items = getInventoryArray();
		final java.util.List<Integer> possible = new ArrayList<Integer>();
		for (int i = 0; i < items.length; i++) {
			if (items[i] == itemID) {
				possible.add(i);
			}
		}
		if (possible.size() == 0) {
			return false;
		}
		final int idx = possible.get(random(0, possible.size()));
		final Point t = getInventoryItemPoint(idx);
		clickMouse(t, 5, 5, true);
		return true;
	}

	public void serverMessageRecieved(final ServerMessageEvent m) {
		if (m.getMessage().contains("bury")) {
			buried++;
		}
		if (m.getMessage().contains("You've just advanced")) {
			clickContinue();
		}
	}

	public void withdraw() {
		if (bank.getCount(BoneID) == 0) {
			log("Could not find any bones in the bank.");
			log("Closing script.");
			bank.close();
			ScreenshotUtil.takeScreenshot(isLoggedIn());
			stopAllScripts();
		}
		bank.withdraw(BoneID, 0);
		wait(random(200, 400));
		if (getInventoryCount(BoneID) > 0) {
			bank.close();
		}
	}
}
